unit MainUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ExtCtrls, StdCtrls, ImgList, DB, ADODB, TcpFileClient,
  SUISkinEngine;

type        

  TfrmBatchUpdateMain = class(TForm)
    Panel1: TPanel;
    lvMain: TListView;
    btnStart: TButton;
    btnStop: TButton;
    pbView: TProgressBar;
    lblStatus: TLabel;
    ilMain: TImageList;
    Database: TADOConnection;
    suiSkinEngine1: TsuiSkinEngine;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Timer1Timer(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
    FHost: string;
    FPort: Integer;
    FAbort: Boolean;
    FTcpCli: TTcpCompareClient;
    FGameList: TStrings;
    FAll: Boolean;
    procedure OnTcpEvent( AStatus: string;
                          AAllSize, ACurSize,
                          AFileAllSize, AFileCurSize: Int64;
                          ASpeed: Double;
                          ARemainTime: TDateTime);
    procedure LoadSoftware;
    procedure DBInit;
    procedure LoadClientGroup;
    procedure CheckParam;
  public
    { Public declarati ons }
  end;

var
  frmBatchUpdateMain: TfrmBatchUpdateMain;

implementation

uses ConstUnit, PublicUnit, FunctionUnit, ProtocolUnit, VDUnit,
  SyncNodeUtil;

{$R *.dfm}

{ TfrmBatchUpdateMain }

procedure TfrmBatchUpdateMain.DBInit;
begin
  Database.ConnectionString := Format(DBFormat, [ExtractFilePath(ParamStr(0)) + 'Data\BarData.mdb']);
  Database.Open;
end;

procedure TfrmBatchUpdateMain.LoadSoftware;
var
  pRec: PSoftwareRec;
  Query: TADOQuery;
  Sql: string;
  li: TListItem;
  ms: TMemoryStream;
  bmp, bmp1: TBitmap;
  i: Integer;
begin
  for i := 0 to lvMain.Items.Count - 1 do
    if (lvMain.Items[i].Data <> nil) then
      FreeMem( lvMain.Items[i].Data );
  lvMain.Clear;
  ilMain.Clear;

  lvMain.Items.BeginUpdate;
  Query := TADOQuery.Create(Self);
  try
    Sql := Format('SELECT * FROM Software WHERE SoftwareUpdateMode = %d', [Integer(smTcp)]);
    OpenDataSet(Sql, Query, Database);
    while not Query.Eof do
    begin
      New( pRec );
      pRec^.SoftwareId := Query.FieldByName('SoftwareId').AsInteger;
      pRec^.SoftwareName := Query.FieldByName('SoftwareName').AsString;
      pRec^.SoftwareGroupId := Query.FieldByName('SoftwareGroupId').AsInteger;
      pRec^.SoftwareServerPath := Query.FieldByname('SoftwareServerPath').AsString;
      pRec^.SoftwareClientPath := Query.FieldByName('SoftwareClientPath').AsString;
      pRec^.SoftwareMainExe := Query.FieldByname('SoftwareMainExe').AsString;
      pRec^.SoftwareIndexFile := Query.FieldByName('SoftwareIndexFile').AsString;
      pRec^.SoftwareSize := Query.FieldByName('SoftwareSize').AsInteger;
      pRec^.Update := Query.FieldByName('UpdateTime').AsDateTime;

      li := lvMain.Items.Add;
      li.Checked := True;
      li.Caption := pRec^.SoftwareName;
      li.Data := pRec;
      li.SubItems.Add(Format('%dk', [pRec^.SoftwareSize]));
      li.SubItems.Add(FormatDateTime('YYYY-MM-DD HH:MM:SS', pRec^.Update));
      ms := TMemoryStream.Create;
      try
        TBlobField( Query.FieldByName('SoftwareIcon') ).SaveToStream( ms );
        ms.Position := 0;
        bmp := TBitmap.Create;
        try
          bmp.LoadFromStream( ms );
          bmp1 := TBitmap.Create;
          try
            bmp1.Width := ilMain.Width;
            bmp1.Height := ilMain.Height;
            bmp1.Canvas.StretchDraw(Rect(0, 0, bmp1.Width, bmp1.Height), bmp);
            li.ImageIndex := ilMain.Add(bmp1, nil);

          finally
            bmp1.Free;
          end;
        finally
          bmp.Free;
        end;
      finally
        ms.Free;
      end;

      if ParamCount > 0 then
        if FAll then
          li.Checked := True
        else
          li.Checked := (FGameList.IndexOf(li.Caption) > -1);
      Query.Next;
    end;
  finally
    Query.Free;
  end;
  lvMain.Items.EndUpdate;
end;

procedure TfrmBatchUpdateMain.FormCreate(Sender: TObject);
begin
  FGameList := TStringList.Create;
  CheckParam;
  DBInit;
  LoadClientGroup;
  LoadSoftware;
  FAbort := False;
end;

procedure TfrmBatchUpdateMain.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to lvMain.Items.Count - 1 do
    if (lvMain.Items[i].Data <> nil) then
      FreeMem( lvMain.Items[i].Data );
  lvMain.Clear;
  FGameList.Free;
end;

procedure TfrmBatchUpdateMain.OnTcpEvent(AStatus: string; AAllSize,
  ACurSize, AFileAllSize, AFileCurSize: Int64; ASpeed: Double;
  ARemainTime: TDateTime);
begin
  if FAbort then
    Exit;
  
  pbView.Max := AAllSize div 1024;
  pbView.Min := 0;
  pbView.Position := ACurSize div 1024;

  lblStatus.Caption := AStatus + Format(' %.2f M/S', [ASpeed / 1024 / 1024]) + '  Left time: ' + FormatDateTime('HH:MM:SS', ARemainTime);
end;

procedure TfrmBatchUpdateMain.btnStartClick(Sender: TObject);
var
  ClientPath, ClientDrive: string;
  i: Integer;
  pRec: PSoftwareRec;

  procedure GetServerFromTracker;
  var
    SL, SL1: TStrings;
    S: string;
  begin
//    SL := TStringList.Create;
//    try
//      LogMenuMessage('GetTrackServer...');
//      ParseLine(GetTrackServer, ':', SL);
//      LogMenuMessage('GetTrackServer - ' + SL.CommaText);
//      if SL.Count = 2 then
//      begin
        SL1 := TStringList.Create;
        try
          LogMessage('TrackGet...' + GetSysParams(CommServerIp, Database));
          S := '';
          S := TrackGet(GetSysParams(CommServerIp, Database){SL[0]});
          LogMessage(s);
          if (S = '') or (S = 'null') then
          begin
            FHost := GetSysParams(ServerIps, Database);
            FPort := TcpFilePort;
            Exit;
          end;
          FunctionUnit.ParseLine(S, ':', SL1);
          if SL1.Count <> 2 then
            Exit;
          FHost := SL1[0];
          FPort := StrToIntDef(SL1[1], TcpFilePort);
          if not CheckTcpServer(FHost, FPort) then
            FHost := GetSysParams(ServerIps, Database);
        finally
          SL1.Free;
        end;
//      end;
//    finally
//      SL.Free;
//    end;
  end;
begin
  GetServerFromTracker;
  ClientDrive := GetSysParams(WtRestoreOption, Database);
  if ClientDrive = '' then
    ClientDrive := 'D';
  if not CheckTcpServer(FHost, FPort) then
    Exit;

  try
    for i := 0 to lvMain.Items.Count - 1 do
    begin
      if FAbort then
        Break;
      if not lvMain.Items[i].Checked then
        Continue;

      lvMain.Items[i].Selected := True;
      Application.ProcessMessages;
      pRec := lvMain.Items[i].Data;
      Mount9Disk;
  //    LogMenuMessage('Mount9Disk');

      ClientPath := pRec^.SoftwareServerPath;
//      ClientPath := '1' + Copy(ClientPath, 2, Length(ClientPath));
      ClientPath := ClientDrive + Copy(ClientPath, 2, Length(ClientPath));
      FTcpCli := TTcpCompareClient.Create(pRec^.SoftwareServerPath, ClientPath, FHost, FPort,
                                          pRec^.SoftwareIndexFile,
                                          IncludeTrailingPathDelimiter(ClientPath) + ExtractFileName(pRec^.SoftwareIndexFile),
                                          False, False, True);
      try
        FTcpCli.OnCompareCopyEvent := OnTcpEvent;
        FTcpCli.DoStart;
      finally
        FreeAndNil(FTcpCli);
      end;

    end;

  finally
    if ParamCount > 0 then
      Close;
  end;


end;

procedure TfrmBatchUpdateMain.LoadClientGroup;
var
  Sql, ComputerName: string;
  Query: TADOQuery;
begin
  ComputerName := GetLocalComputerName;

  Sql := Format('SELECT g.* FROM Groups as g Left JOIN ' +
                ' ComputerGroup AS cg ON cg.GroupId = g.GroupId WHERE cg.ComputerName = "%s"', [ComputerName]);
  Query := TADOQuery.Create( nil );
  try
    OpenDataSet(Sql, Query, Database);
    if Query.IsEmpty then
      Exit;

//    FHost := Query.FieldByName('TcpFileHost').AsString;
//    FPort := Query.FieldByName('TcpFilePort').AsInteger;
//    FVNDHost := Query.FieldByName('VDiskIp').AsString;
//    FVNDPort := Query.FieldByName('VDiskPort').AsString;
//    if FPort = 0 then
//      FPort := TcpFilePort;

  finally
    Query.Free;
  end;

  FHost := GetSysParams(ServerIps, Database);
  FPort := TcpFilePort;  
end;

procedure TfrmBatchUpdateMain.btnStopClick(Sender: TObject);
begin
  if Assigned( FTcpCli ) then
    FTcpCli.DoStop;

  FAbort := True;
end;

procedure TfrmBatchUpdateMain.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  btnStop.Click;
end;

procedure TfrmBatchUpdateMain.CheckParam;
var
  SL: TStrings;
begin
  if ParamCount > 0 then
  begin
    Self.BorderStyle := bsNone;
    Self.Width := 0;
    Self.Height := 0;
    SetWindowLong(Application.Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW);
  end;

  FAll := FindCmdLineSwitch('All', ['-', '/', '\'], False);
  FunctionUnit.ParseLine(ParamStr(1), ',', FGameList);
//    Application.MainForm.Hide;  
end;

procedure TfrmBatchUpdateMain.Timer1Timer(Sender: TObject);
begin
//  Timer1.Enabled := False;
//  if ParamCount > 0 then
//    btnStart.Click;
end;

procedure TfrmBatchUpdateMain.FormActivate(Sender: TObject);
begin
  if ParamCount > 0 then
    btnStart.Click;
end;

end.
